package com.songlanyun.modules.article.service.impl;

import com.songlanyun.common.enums.IntegralConstant;
import com.songlanyun.common.enums.OpusConstant;
import com.songlanyun.common.enums.SysConstant;
import com.songlanyun.common.utils.TransactionUtils;
import com.songlanyun.modules.account.service.UserInfoService;
import com.songlanyun.modules.article.entity.Article;
import com.songlanyun.modules.article.model.vo.UserPointVo;
import com.songlanyun.modules.article.service.ArticleService;
import com.songlanyun.modules.browse.service.BrowseRecordService;
import com.songlanyun.modules.integralconfig.entity.IntegralConfig;
import com.songlanyun.modules.integralconfig.service.IntegralConfigService;
import com.songlanyun.modules.integralrecord.entity.IntegralRecord;
import com.songlanyun.modules.integralrecord.service.IntegralRecordService;
import com.songlanyun.modules.interact.IInteractService;
import com.songlanyun.modules.like.service.LikeRecordService;
import com.songlanyun.modules.message.model.InteractionMessage;
import com.songlanyun.modules.message.model.to.PrivateMessageTO;
import com.songlanyun.modules.message.service.PrivateMessageService;
import com.songlanyun.modules.opus.entity.Opus;
import com.songlanyun.modules.opus.service.OpusService;
import com.songlanyun.modules.share.service.ShareRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author lubo
 * @email sunlightcs@gmail.com
 * @date 2021-01-13 16:35:02
 */
@Service("articleInteractService")
public class ArticleInteractServiceImpl implements IInteractService {

    @Resource
    private LikeRecordService likeRecordService;
    @Resource
    private ShareRecordService shareRecordService;
    @Resource
    private ArticleService articleService;
    @Resource
    private BrowseRecordService browseRecordService;
    @Resource
    private IntegralRecordService integralRecordService;
    @Resource
    private IntegralConfigService integralConfigService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private TransactionUtils transactionUtils;

    @Override
    public void browseSave(BoundHashOperations<String, String, Object> result) {
        //文章浏览
        result.entries().forEach((m, n) -> {
            AtomicReference<Integer> sum = new AtomicReference<>(0);//浏览总数
            AtomicReference<Integer> total = new AtomicReference<>(0);//浏览人数
            List<UserPointVo> collect = mapToSortUserPointVoList((HashMap<String, Object>) n);   //{11={1:2020-01-01}}, 22={1:2020-01-01}}

            TransactionStatus transactionStatus = transactionUtils.begin();
            try {
                //获得文章
                Long articleId = Long.parseLong(m);
                Article article = articleService.getById(articleId);

                if (article != null && collect != null) {
                    collect.forEach((c) -> {
                        Long userId = c.getUserId();//11
                        Map<String, Object> numTimeMap = c.getValue();//{1:2020-01-01}
                        Integer count = (Integer) numTimeMap.get("num");
                        Date time = (Date) numTimeMap.get("time");//最后一次更新时间

                        //总浏览数
                        sum.set(sum.get() + count);
                        //articleId、userId、去查询浏览表记录，如果不存在记录，则保存浏览记录
                        Boolean browse = browseRecordService.browse(OpusConstant.ModelType.ARTICLE, articleId, userId, article.getCreator(), time);
                        if (browse) {
                            //计算浏览人数，不存在记录时统计
                            total.set(total.get() + 1);
                        }
                        //是否已赠送积分
                        Boolean exists = integralRecordService.exists(OpusConstant.ModelType.ARTICLE, articleId, userId, IntegralConstant.InnerMode.BROWSE);
                        if (!exists) {
                            //浏览人获得积分  -- 发送mq消息
                            IntegralConfig config = integralConfigService.get();
                            String name = userInfoService.getNameById(userId);
                            IntegralRecord record = new IntegralRecord(userId, config.getBrowse(), IntegralConstant.InnerMode.BROWSE,
                                    IntegralConstant.IntegralModelType.ARTICLE, articleId, "");
                            record.setRemark(String.format("会员【%s】浏览文章【%s】，获得积分:%s", name, article.getTitle(), record.getValue()));
                            integralRecordService.inner(record);
                        }
                    });
                    //更新作品表浏览总数，浏览人数
                    article.addBrowseNum(total.get());
                    article.addBrowseSum(sum.get());
                }
                //删除redis缓存
                result.delete(m);
                transactionUtils.commit(transactionStatus);
            } catch (Exception ex) {
                transactionUtils.rollback(transactionStatus);
                throw ex;
            }

        });
    }

    @Override
    public void likeSave(BoundHashOperations<String, String, Object> result) {
        //文章点赞
        result.entries().forEach((m, n) -> {
            AtomicReference<Integer> num = new AtomicReference<>(0);//点赞人数
            List<UserPointVo> collect = mapToSortUserPointVoList((HashMap<String, Object>) n);
            TransactionStatus transactionStatus = transactionUtils.begin();
            try {
                //获得作品
                Long articleId = Long.parseLong(m);
                Article article = articleService.getById(articleId);

                if (article != null && collect != null) {
                    collect.forEach((c) -> {
                        Long userId = c.getUserId();//11
                        Map<String, Object> numTimeMap = c.getValue();//{1:2020-01-01}
//                    Integer count = (Integer) numTimeMap.get("num");
                        Date time = (Date) numTimeMap.get("time");//最后一次更新时间

                        //根据opusId、userId、去查询点赞记录，如果不存在记录，则保存浏览记录
                        Boolean like = likeRecordService.like(OpusConstant.ModelType.ARTICLE, articleId, userId, article.getCreator(), time);
                        if (like) {
                            //计算点赞人数，不存在记录时统计
                            num.set(num.get() + 1);
                        }
                        //是否已赠送积分
                        Boolean exists = integralRecordService.exists(OpusConstant.ModelType.ARTICLE, articleId, userId, IntegralConstant.InnerMode.LIKE);
                        if (!exists) {
                            IntegralConfig config = integralConfigService.get();
                            if (config != null) {
                                //点赞人获得积分
                                String name = userInfoService.getNameById(userId);
                                IntegralRecord record = new IntegralRecord(userId, config.getLike(), IntegralConstant.InnerMode.LIKE,
                                        IntegralConstant.IntegralModelType.ARTICLE, articleId, "");
                                record.setRemark(String.format("会员【%s】点赞文章【%s】，获得积分:%s", name, article.getTitle(), record.getValue()));
                                integralRecordService.inner(record);
                            }

                        }
                    });
                    //更新作品表点赞人数
                    article.addLikeNum(num.get());
                }
                //删除redis缓存
                result.delete(m);
                transactionUtils.commit(transactionStatus);
            } catch (Exception ex) {
                transactionUtils.rollback(transactionStatus);
                throw ex;
            }

        });

    }

    @Override
    public void shareSave(BoundHashOperations<String, String, Object> result) {
        //作品分享
        result.entries().forEach((m, n) -> {
            AtomicReference<Integer> sum = new AtomicReference<>(0);//分享总数
            AtomicReference<Integer> num = new AtomicReference<>(0);//分享人数
            List<UserPointVo> collect = mapToSortUserPointVoList((HashMap<String, Object>) n);
            TransactionStatus transactionStatus = transactionUtils.begin();
            try {
                //获得作品
                Long articleId = Long.parseLong(m);
                Article article = articleService.getById(articleId);

                if (article != null && collect != null) {
                    collect.forEach((c) -> {
                        Long userId = c.getUserId();//11
                        Map<String, Object> numTimeMap = c.getValue();//111
                        Integer count = (Integer) numTimeMap.get("num");
                        Date time = (Date) numTimeMap.get("time");//最后一次更新时间
                        sum.set(sum.get() + count);

                        //根据opusId、userId、去查询分享表记录，如果不存在记录，则保存分享记录
                        Boolean share = shareRecordService.share(OpusConstant.ModelType.ARTICLE, articleId, userId, article.getCreator(), time);
                        if (share) {
                            //计算分享人数，不存在记录时统计
                            num.set(num.get() + 1);
                        }
                        //是否已赠送积分
                        Boolean exists = integralRecordService.exists(OpusConstant.ModelType.ARTICLE, articleId, userId, IntegralConstant.InnerMode.SHARE);
                        if (!exists) {
                            IntegralConfig config = integralConfigService.get();
                            if (config != null) {
                                //分享人获得积分
                                String name = userInfoService.getNameById(userId);
                                IntegralRecord record = new IntegralRecord(userId, config.getBrowse(), IntegralConstant.InnerMode.SHARE,
                                        IntegralConstant.IntegralModelType.ARTICLE, articleId, "");
                                record.setRemark(String.format("会员【%s】分享文章【%s】，获得积分:%s", name, article.getTitle(), record.getValue()));
                                integralRecordService.inner(record);
                            }

                        }
                    });
                    //更新作品表分享总数，分享人数
                    article.addShareNum(num.get());
                    article.addShareSum(sum.get());
                }
                //删除redis缓存
                result.delete(m);
                transactionUtils.commit(transactionStatus);
            } catch (Exception ex) {
                transactionUtils.rollback(transactionStatus);
                throw ex;
            }
        });
    }


}

